<template>
  <div class="game-container">
    <div class="game-header">
      <div class="mines-counter">{{ remainingMines }}</div>
      <button class="reset-button" @click="resetGame">{{ statusIcon }}</button>
      <div class="timer">{{ gameTime }}</div>
    </div>
    <div class="game-header">
      <div class="level" :class="gameLevel == 'jd' ? 'active' : ''" @click="selectLevel('jd')">简单</div>
      <div class="level" :class="gameLevel == 'zd' ? 'active' : ''" @click="selectLevel('zd')">中等</div>
      <div class="level" :class="gameLevel == 'kn' ? 'active' : ''" @click="selectLevel('kn')">困难</div>
    </div>

    <div class="grid">
      <div
          v-for="(row, x) in grid"
          :key="x"
          class="row"
      >
        <div
            v-for="(cell, y) in row"
            :key="y"
            class="cell"
            :class="{
            'revealed': cell.revealed,
            'mine': cell.isMine && gameOver,
            'flagged': cell.flagged
          }"
            @click.left="reveal(x, y)"
            @click.right.prevent="flag(x, y)"
        >
          <template v-if="cell.revealed">
            {{ cell.isMine ? '💣' : cell.neighborMines || '' }}
          </template>
          <template v-else>
            {{ cell.flagged ? '🚩' : '' }}
          </template>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data(){
    return{
      gameLevel: 'jd',
      rrid_size: 9,
      grid_size: 9,
      mines_count: 10,
      gameOver: false,
      gameWon: false,
      startTime: 0,
      gameTime: 0,
      timerInterval: null,
      grid: [],
    }
  },
  computed: {
    remainingMines(){
      const flagsUsed = this.grid.flat().filter(cell => cell.flagged).length
      return this.mines_count - flagsUsed
    },
    statusIcon(){
      if (this.gameWon) return '😎'
      if (this.gameOver) return '😵'
      return '😀'
    }
  },
  mounted() {
    this.initializeGrid()
  },
  methods: {
    //初始化雷区
    initializeGrid() {
      this.gameOver = false
      this.gameWon = false
      this.grid.length = 0

      // 创建空网格
      for (let x = 0; x < this.grid_size; x++) {
        this.grid[x] = []
        for (let y = 0; y < this.rrid_size; y++) {
          this.grid[x][y] = {
            isMine: false,
            revealed: false,
            flagged: false,
            neighborMines: 0
          }
        }
      }

      // 放置地雷
      let minesPlaced = 0
      while (minesPlaced < this.mines_count) {
        const x = Math.floor(Math.random() * this.grid_size)
        const y = Math.floor(Math.random() * this.rrid_size)
        if (!this.grid[x][y].isMine) {
          this.grid[x][y].isMine = true
          minesPlaced++
        }
      }

      // 计算相邻地雷数量
      for (let x = 0; x < this.grid_size; x++) {
        for (let y = 0; y < this.rrid_size; y++) {
          if (!this.grid[x][y].isMine) {
            this.grid[x][y].neighborMines = this.countNeighborMines(x, y)
          }
        }
      }
    },
    selectLevel(type){
      this.gameLevel = type
      if(type == 'jd'){
        this.rrid_size = 8
        this.grid_size = 8
        this.mines_count = 10
      }
      if(type == 'zd'){
        this.rrid_size = 16
        this.grid_size = 16
        this.mines_count = 40
      }
      if(type == 'kn'){
        this.rrid_size = 30
        this.grid_size = 16
        this.mines_count = 99
      }
      this.initializeGrid()
    },
    countNeighborMines(x, y) {
      let count = 0
      for (let dx = -1; dx <= 1; dx++) {
        for (let dy = -1; dy <= 1; dy++) {
          const nx = x + dx
          const ny = y + dy
          if (nx >= 0 && nx < this.grid_size && ny >= 0 && ny < this.rrid_size) {
            if (this.grid[nx][ny].isMine) count++
          }
        }
      }
      return count
    },
    //点击
    reveal(x, y) {
      if (this.gameOver || this.grid[x][y].flagged){
        if(this.timerInterval){
          clearInterval(this.timerInterval)
          this.timerInterval = null
        }
        return;
      }
      if(!this.timerInterval){
        this.startTime = Date.now()
        this.gameTime = 0
        clearInterval(this.timerInterval)
        this.timerInterval = null
        this.timerInterval = setInterval(() => {
          this.gameTime = Math.floor((Date.now() - this.startTime) / 1000)
        }, 1000)
      }

      if (this.grid[x][y].isMine) {
        this.gameOver = true
        clearInterval(this.timerInterval)
        this.timerInterval = 0
        this.revealAllMines()
        return
      }

      this.revealRecursive(x, y)
      this.checkWin()
    },
    revealRecursive(x, y) {
      if (x < 0 || x >= this.grid_size || y < 0 || y >= this.rrid_size) return
      if (this.grid[x][y].revealed || this.grid[x][y].flagged) return

      this.grid[x][y].revealed = true

      if (this.grid[x][y].neighborMines === 0) {
        for (let dx = -1; dx <= 1; dx++) {
          for (let dy = -1; dy <= 1; dy++) {
            this.revealRecursive(x + dx, y + dy)
          }
        }
      }
    },
    flag(x, y) {
      if (!this.gameOver && !this.grid[x][y].revealed) {
        this.grid[x][y].flagged = !this.grid[x][y].flagged
        this.checkWin()
      }
    },
    revealAllMines() {
      for (let x = 0; x < this.grid_size; x++) {
        for (let y = 0; y < this.rrid_size; y++) {
          if (this.grid[x][y].isMine) {
            this.grid[x][y].revealed = true
          }
        }
      }
    },
    checkWin() {
      let correctFlags = 0
      let requiredFlags = this.mines_count

      for (let x = 0; x < this.grid_size; x++) {
        for (let y = 0; y < this.rrid_size; y++) {
          if (this.grid[x][y].isMine && this.grid[x][y].flagged) correctFlags++
          if (!this.grid[x][y].isMine && !this.grid[x][y].revealed) requiredFlags++
        }
      }

      if (correctFlags === this.mines_count && requiredFlags === this.mines_count) {
        this.gameWon = true
        this.gameOver = true
        clearInterval(this.timerInterval)
        this.timerInterval = 0
        setTimeout(() => {
          let obj = JSON.parse(localStorage.getItem("lastname")) || {}
          if(this.gameTime < obj[this.gameLevel] || !obj[this.gameLevel]){
            obj[this.gameLevel] = this.gameTime;
            localStorage.setItem("lastname", JSON.stringify(obj));
          }
          confirm(`当前所用时间为${this.gameTime}秒，最短时间为${obj[this.gameLevel]}秒`)
        },500)
      }
    },
    resetGame() {
      clearInterval(this.timerInterval)
      this.timerInterval = 0
      this.gameTime = 0
      this.initializeGrid()
    }
  }
}
</script>
<style scoped>
.game-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: Arial, sans-serif;
}

.level{
  color: aquamarine;
  cursor: pointer;
}
.active{
  color: blue;
}

.game-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 300px;
  margin-bottom: 10px;
  padding: 10px;
  background: #c0c0c0;
  border: 3px outset #fff;
}

.mines-counter, .timer {
  width: 50px;
  height: 35px;
  background: #000;
  color: red;
  font-size: 25px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: monospace;
}

.reset-button {
  width: 35px;
  height: 35px;
  font-size: 20px;
  border: 2px outset #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.grid {
  background: #c0c0c0;
  padding: 10px;
  border: 3px outset #fff;
}

.row {
  display: flex;
}

.cell {
  width: 30px;
  height: 30px;
  border: 2px outset #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: bold;
  background: #c0c0c0;
  cursor: pointer;
  user-select: none;
}

.cell.revealed {
  width: 32px;
  height: 32px;
  border: 1px solid #808080;
  background: #c0c0c0;
}

.cell.mine {
  background: red;
}

.cell.flagged {
  color: red;
}

/* 数字颜色 */
.cell.revealed:nth-child(1) { color: blue; }
.cell.revealed:nth-child(2) { color: green; }
.cell.revealed:nth-child(3) { color: red; }
.cell.revealed:nth-child(4) { color: darkblue; }
.cell.revealed:nth-child(5) { color: brown; }
.cell.revealed:nth-child(6) { color: cyan; }
.cell.revealed:nth-child(7) { color: black; }
.cell.revealed:nth-child(8) { color: gray; }
</style>